/**
 * 62. 不同路径
 */
public class Solution_62 {
    /**
     * 方法二：组合数学
     * <p>
     * 从左上角到右下角，需要向下移动 m-1 次，向右移动 n-1 次，共 m+n-2 次。
     * <p>
     * 因此路径总数就等于从 m+n-2 次移动中选择 m-1 次向下移动，即 C(m+n−2, m−1)
     */
    public int uniquePaths(int m, int n) {
        long ans = 1;
        for (int x = n, y = 1; y < m; x++, y++) {
            ans = ans * x / y;
        }
        return (int) ans;
    }

    /**
     * 方法一：动态规划
     * <p>
     * f(i,j) 表示从左上角走到 (i,j) 的路径数量
     * <p>
     * 状态转移方程：f[i][j] = f[i - 1][j] + f[i][j - 1];
     */
    public int uniquePaths1(int m, int n) {
        int[][] f = new int[m][n];
        // 最左边的列
        for (int i = 0; i < m; i++) {
            f[i][0] = 1;
        }
        // 最上边的行
        for (int i = 0; i < n; i++) {
            f[0][i] = 1;
        }
        // 动态规划
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                f[i][j] = f[i - 1][j] + f[i][j - 1];
            }
        }
        return f[m - 1][n - 1];
    }

    public static void main(String[] args) {
        Solution_62 solution = new Solution_62();
        int m = 3, n = 7;
        int ans = solution.uniquePaths(m, n);
        System.out.println(ans);
    }
}